
import { TrainingParameters, TaskType } from '../types';

interface SimulationCallbacks {
  onProgress: (epoch: number, step: number, totalSteps: number, loss: number, accuracy: number) => void;
  onEpochComplete: (epoch: number, loss: number, accuracy: number) => void;
  onComplete: (message: string) => void;
  onStatusUpdate: (message: string) => void;
}

class Simulation {
  private intervalId: number | null = null;
  private isRunning = false;

  public start(params: TrainingParameters, type: TaskType, callbacks: SimulationCallbacks) {
    if (this.isRunning) {
      console.warn("Simulation is already running.");
      return;
    }

    this.isRunning = true;
    let currentEpoch = 1;
    let currentStep = 0;
    const stepsPerEpoch = 50; // Mock steps
    let loss = 0.8 + Math.random() * 0.2;
    let accuracy = 0.5 + Math.random() * 0.2;

    callbacks.onStatusUpdate(`[${type}] 任务初始化... 设备: CUDA`);

    this.intervalId = window.setInterval(() => {
      if (!this.isRunning) {
        if(this.intervalId) clearInterval(this.intervalId);
        return;
      }

      currentStep++;
      
      // Simulate metric changes
      loss -= (0.005 + Math.random() * 0.005) * (1 / currentEpoch);
      accuracy += (0.008 + Math.random() * 0.005) * (1 / currentEpoch);
      loss = Math.max(loss, 0.01);
      accuracy = Math.min(accuracy, 0.99);

      callbacks.onProgress(currentEpoch, currentStep, stepsPerEpoch, loss, accuracy);

      if (currentStep >= stepsPerEpoch) {
        callbacks.onEpochComplete(currentEpoch, loss, accuracy);
        callbacks.onStatusUpdate(`[${type}] 第 ${currentEpoch}/${params.numEpochs} 轮完成。`);
        
        currentStep = 0;
        currentEpoch++;

        if (currentEpoch > params.numEpochs) {
          if(this.intervalId) clearInterval(this.intervalId);
          this.isRunning = false;
          callbacks.onComplete(`[${type}] 任务已成功完成！`);
        }
      }
    }, 100); // Update every 100ms
  }

  public stop() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
    this.isRunning = false;
    console.log("Simulation stopped by user.");
  }
}

export const simulationService = new Simulation();
